﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Transactions;
using Tauren.Business.DLL.Base;
using Tauren.Business.DLL.ButtonDLL;
using Tauren.Business.DLL.Resouces;
using Tauren.Business.Entity.Config;
using Tauren.Business.Entity.Const;
using Tauren.Business.Entity.Enum;
using Tauren.Business.Entity.Global;
using Tauren.Business.Entity.Input;
using Tauren.Business.Entity.Model;
using Tauren.Business.Entity.Output;
using Tauren.Business.Infrastructure.Common;
using Tauren.Business.Infrastructure.Globals;

namespace Tauren.Business.Service.ButtonBLL
{
    public class ButtonService : Base.BaseService, IButtonService
    {
        private IButtonsBusiness business;
        public ButtonService(IButtonsBusiness _business, IConnectionBLLBase connectionBLL, IMenuResourcesBusiness resBusiness) : base(_business, connectionBLL, resBusiness)
        {
            this.ResourcesInfo = GetResources(GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY);
            this.JudePrmission(GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower());
            this.business = _business;
        }

        public IResponseMessage Config(string PageType)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            List<OutPutConfig> Fields = new List<OutPutConfig>();

            OutPutConfig config = new OutPutConfig();
            config.Label = this.Resources("thautoid");
            config.FieldKey = "autoId";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.number;
            Fields.Add(config);
            config = new OutPutConfig();
            config.Label = this.Resources("thcode");
            config.FieldKey = "value";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.text;
            config.Show = true;
            config.Editor = PageType != "view" && PageType != "edit";
            config.Required = PageType != "view" && PageType != "edit";
            Dictionary<object, object> rule = new Dictionary<object, object>();
            if (PageType != "view")
            {
                #region 添加验证规则

                rule.Add("required", true);
                rule.Add("message", this.Resources("valuerequired"));
                rule.Add("trigger", "blur");
                config.Rules.Add(rule);
                ///长度
                rule = new Dictionary<object, object>();
                rule.Add("min", 1);
                rule.Add("max", 30);
                rule.Add("message", this.Resources("valuelength"));
                rule.Add("trigger", "blur");
                config.Rules.Add(rule);
                ///正则
                rule = new Dictionary<object, object>();
                rule.Add("pattern", "^([a-z0-9]){1,30}$");
                rule.Add("message", this.Resources("valueregex"));
                rule.Add("trigger", "blur");
                config.Rules.Add(rule);
            }
            #endregion
            Fields.Add(config);

            config = new OutPutConfig();
            config.Label = this.Resources("thtype");
            config.FieldKey = "type";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.parameter;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            config.Options = new List<Options>() {
                new Options { Label="Default",Value= "" },
                new Options { Label=BtnColorType.info.ToString(),Value= BtnColorType.info.ToString() },
                new Options { Label=BtnColorType.danger.ToString(),Value= BtnColorType.danger.ToString() },
                new Options { Label=BtnColorType.success.ToString(),Value= BtnColorType.success.ToString() },
                new Options { Label=BtnColorType.warning.ToString(),Value= BtnColorType.warning.ToString() },
                new Options { Label=BtnColorType.primary.ToString(),Value= BtnColorType.primary.ToString() },
            };
            Fields.Add(config);

            config = new OutPutConfig();
            config.Label = this.Resources("thicon");
            config.FieldKey = "icon";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.icon;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            Fields.Add(config);

            config = new OutPutConfig();
            config.Label = this.Resources("thsize");
            config.FieldKey = "size";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.parameter;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            config.Options = new List<Options>() {
                new Options { Label="Default",Value= "" },
                new Options { Label=BtnSizeType.medium.ToString(),Value= BtnSizeType.medium.ToString() },
                new Options { Label=BtnSizeType.small.ToString(),Value= BtnSizeType.small.ToString() },
                new Options { Label=BtnSizeType.mini.ToString(),Value= BtnSizeType.mini.ToString() }
            };
            Fields.Add(config);

            config = new OutPutConfig();
            config.Label = this.Resources("thshape");
            config.FieldKey = "shape";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.parameter;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            config.Options = new List<Options>() {
                new Options { Label="Default",Value= "" },
                new Options { Label=BtnShapeType.round.ToString(),Value= BtnShapeType.round.ToString() },
                new Options { Label=BtnShapeType.plain.ToString(),Value= BtnShapeType.plain.ToString() },
                new Options { Label=BtnShapeType.circle.ToString(),Value= BtnShapeType.circle.ToString() }
            };
            Fields.Add(config);

            config = new OutPutConfig();
            config.Label = this.Resources("thlocation");
            config.FieldKey = "location";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.parameter;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            config.Options = new List<Options>() {
                new Options { Label="Default",Value= "" },
                new Options { Label=ButtomLocation.top.ToString(),Value= ButtomLocation.top.ToString() },
                new Options { Label=ButtomLocation.center.ToString(),Value= ButtomLocation.center.ToString() },
                new Options { Label=ButtomLocation.bottom.ToString(),Value= ButtomLocation.bottom.ToString() }
            };
            Fields.Add(config);

            config = new OutPutConfig();
            config.Label = this.Resources("thdicisuserflow");
            config.FieldKey = "isUseFlow";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_OPERATION_KEY.ToLower();
            config.ControlType = ControlType.radio;
            config.Show = true;
            config.Editor = PageType != "view";
            config.Required = PageType != "view";
            config.Options = new List<Options>() {
                new Options { Label=this.Resources("trtrue"),Value= true },
                new Options { Label=this.Resources("trfalse"),Value= false },
            };
            Fields.Add(config);

            config = new OutPutConfig();
            config.FieldKey = "childFieldValues";
            config.MenuCode = GlobalConst.RESOURCES_FLAG_MODULE_KEY.ToLower();
            config.ControlType = ControlType.records;
            config.Show = true;
            config.Editor = PageType != "view";
            BuliedTableResConfig(config.Tables, PageType);
            Fields.Add(config);
            config.Label = this.Resources("value");
            return Fields.Succeed();
        }

        public IResponseMessage Edit(Button_Input data)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA));
            var singe = business.Singe(data.AutoId);
            if (singe is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            if (data.ChildFieldValues is null || !data.ChildFieldValues.Any()) return GlobalErrorType.GLOBAL_RES_LANGUAGE_REPEAT_ERROR.Failure(this.Resources(GlobalErrorType.GLOBAL_RES_LANGUAGE_REPEAT_ERROR));
            int Msg = 0;
            string lan = "";
            bool repeat = ValueRepeat(data.ChildFieldValues, out Msg, out lan);
            if (!repeat) return Msg.Failure(string.Format(this.CommonText(Msg), lan));
            Buttons btn = null;
            ToModel(data, out btn);
            btn.Creator = singe.Creator;
            btn.Creatdate = singe.Creatdate;
            btn.Modifdate = DateTime.Now;
            btn.Modifier = Global.EmpId;
            using (TransactionScope ts = new TransactionScope())
            {
                bool b = business.Edit(btn);
                if (b)
                {
                    List<Entity.Model.ButtonRes> res = new List<Entity.Model.ButtonRes>();
                    foreach (var item in data.ChildFieldValues)
                    {
                        res.Add(new Entity.Model.ButtonRes() { Language = item.Language, Value = item.Value, BtnId = singe.BtnId });
                    }
                    b = business.Add(res);
                    if (b)
                    {
                        ts.Complete();
                    }
                    return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
                }
                else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
            }
        }

        public IResponseMessage Get(long AutoID)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            List<ButtonsTable> tables = business.Get(AutoID);
            Button_OutPut _OutPut = new Button_OutPut();
            if (tables != null && tables.Any())
            {
                ButtonsTable table = tables.FirstOrDefault();
                ToViewModel(table, out _OutPut);
                _OutPut.Value = table.Code;
                if (!(_OutPut is null))
                {
                    _OutPut.ChildFieldValues = new List<ButtonRes_OutPut>();
                    tables.GroupBy(p => new { p.BtnId, p.AutoId }).ToList().ForEach(o =>
                    {
                        o.ToList().ForEach(chd =>
                        {
                            _OutPut.ChildFieldValues.Add(new ButtonRes_OutPut() { BtnId = chd.BtnId, Language = chd.Language, Value = chd.Value });
                        });
                    });
                }
            }
            else
            {
                _OutPut.ChildFieldValues = new List<ButtonRes_OutPut>() { new ButtonRes_OutPut() { Language = "", Value = "" } };
            }
            return _OutPut.Succeed();
        }

        public IResponseMessage Insert(Button_Input data)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_INPUT_DATA));
            if (data.ChildFieldValues is null || !data.ChildFieldValues.Any()) return GlobalErrorType.GLOBAL_RES_LANGUAGE_REPEAT_ERROR.Failure(this.Resources(GlobalErrorType.GLOBAL_RES_LANGUAGE_REPEAT_ERROR));
            int Msg = 0;
            string lan = "";
            bool repeat = ValueRepeat(data.ChildFieldValues, out Msg, out lan);
            long BtnId = LongCommon.Default.Create();
            if (!repeat) return Msg.Failure(string.Format(this.CommonText(Msg), lan));
            var list = business.All<Buttons>();
            double seq = list == null || !list.Any() ? 0 : list.Max(p => p.Sequence).Value + 1;
            Entity.Model.Buttons buttons = null;
            ToModel<Buttons, Button_Input>(data, out buttons);
            buttons.Sequence = seq;
            buttons.BtnId = BtnId;
            buttons.Creator = Global.EmpId;
            buttons.Creatdate = DateTime.Now;
            buttons.Modifdate = DateTime.Now;
            buttons.Modifier = Global.EmpId;
            using (TransactionScope ts = new TransactionScope())
            {
                long id = business.Add(buttons);
                if (id > 0)
                {
                    List<Entity.Model.ButtonRes> res = new List<Entity.Model.ButtonRes>();
                    foreach (var item in data.ChildFieldValues)
                    {
                        res.Add(new Entity.Model.ButtonRes() { Language = item.Language, Value = item.Value, BtnId = BtnId });
                    }
                    bool b = business.Add(res);
                    if (b)
                    {
                        ts.Complete();
                    }
                    return "".OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_SUCCESSINFO.ToString()));
                }
                else return GlobalErrorType.GLOBAL_SAVE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_SAVE_FAILURE));
            }
        }


        public IResponseMessage Pages(QueryModel queryModel)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            TableListModel<PageButtonsTable> tableListModel = new TableListModel<PageButtonsTable>();
            List<TableListHeaderModele> Headers = new List<TableListHeaderModele>();
            Headers.Add(new TableListHeaderModele() { Key = "rowNo", Name = CommonText("rowNo"), Width = 50, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "autoId", Name = CommonText("autoId"), Width = 70, Type = "primary_key", Align = "center", SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "language", Name = CommonText("languageType"), Width = 120, Align = "center", SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "value", Name = Resources("thvalue"), Type = "primary_name", Align = "left", IsOperation = true });
            Headers.Add(new TableListHeaderModele() { Key = "code", Name = Resources("thcode"), Width = 160, SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "icon", Name = Resources("thicon"), Width = 80, IsIcon = true, Align = "center", SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "type", Name = Resources("thtype"), Width = 80, IsTag = true, Align = "center", SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "size", Name = Resources("thsize"), Width = 80, IsTag = true, Align = "center", SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "shape", Name = Resources("thshape"), IsTag = true, Width = 120, Align = "center", SorTable = SortType.custom.ToString(), Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "dic_IsUserFlow", Name = Resources("thdicisuserflow"), IsTag = true, Width = 100, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "location", Name = Resources("thlocation"), IsTag = true, Width = 120, Align = "center", Filter = true });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creator", Name = Resources("diccreator"), Width = 120, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "dic_Creatdate", Name = Resources("diccreatdate"), Width = 160, Align = "center" });
            Headers.Add(new TableListHeaderModele() { Key = "action", Name = "操作", Width = 160, Align = "center" });
            List<AccountListModel> employeeListModels = new List<AccountListModel>();
            long Total = 0;
            List<PageButtonsTable> Data = business.Pages(queryModel, out Total);
            if (Data.Any())
            {
                Data.ForEach(o =>
                {

                    o.Language = Languages(GlobalConst.LANGUAGE_CONTENT_LANGUAGE_KEY);
                    o.Dic_Creator = EmpDictionary.ContainsKey(o.Creator) ? EmpDictionary[o.Creator] : "";
                    o.Dic_Modifier = EmpDictionary.ContainsKey(o.Modifier) ? EmpDictionary[o.Modifier] : "";
                    o.Dic_Creatdate = o.Creatdate.Value.ToString(GlobalConst.DATE_FORMAT_SECONDS);
                    o.Dic_IsUserFlow = this.Resources($"tr{o.IsUserFlow}");
                    o.Row_Style = "";
                    o.Operations = new List<SystemButton>();
                    if (Global.IsAdmin && (Buttons is null || !Buttons.Any()))
                    {
                        BuliderButtons(o.Operations, o.BtnId.ToString(), o.AutoId, ButtomType.edit);
                        BuliderButtons(o.Operations, o.BtnId.ToString(), o.AutoId, ButtomType.detaile);
                        BuliderButtons(o.Operations, o.BtnId.ToString(), o.AutoId, ButtomType.delete);
                    }
                    else
                    {
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.detaile.ToString()))
                            BuliderButtons(o.Operations, o.BtnId.ToString(), o.AutoId, ButtomType.edit);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.edit.ToString()))
                            BuliderButtons(o.Operations, o.BtnId.ToString(), o.AutoId, ButtomType.detaile);
                        if (Buttons.Any(o => o.Location == ButtomLocation.center.ToString() && o.Value == ButtomType.delete.ToString()))
                            BuliderButtons(o.Operations, o.BtnId.ToString(), o.AutoId, ButtomType.delete);
                    }
                });
            }
            tableListModel.Body = Data;
            tableListModel.Total = Total;
            tableListModel.Header = Headers;
            if (Global.IsAdmin && (Buttons is null || !Buttons.Any()))
            {
                BuliderButtons(tableListModel.Operations, "", 0, ButtomType.add);
            }
            else
            {
                if (Buttons.Any(o => o.Value == ButtomType.add.ToString()))
                    BuliderButtons(tableListModel.Operations, "", 0, ButtomType.add);
            }
            return tableListModel.Succeed();
        }

        public IResponseMessage PhysicallyDeleted(long AutoID)
        {
            if (!HavePermission) return ErrorType.BUSINESS_WITHOUT_PERMISSION.Failure(this.CommonText(ErrorType.BUSINESS_WITHOUT_PERMISSION));
            var data = business.Singe(AutoID);
            if (data is null) return GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA.Failure(this.CommonText(GlobalErrorType.GLOBAL_NOT_FOUND_DB_DATA));
            bool b = business.PhysicallyDeleted(AutoID);
            if (b)
                return "".OnSucceed(this.Resources(GlobalErrorType.GLOBAL_DELETE_SUCCESSINFO));
            else return GlobalErrorType.GLOBAL_DELETE_FAILURE.OnSucceed(this.CommonText(GlobalErrorType.GLOBAL_DELETE_FAILURE));
        }

        public IResponseMessage Template(string key) => new ButtonRes_OutPut() { Language = "", Value = "" }.Succeed();

        #region MyRegion
        private bool ValueRepeat(List<ButtonRes_InPut> ChildFieldValues, out int Msg, out string lan)
        {
            bool b = true;
            Msg = 0;
            lan = "";
            var groups = ChildFieldValues.GroupBy(o => o.Language).Select(n => new { Language = n.Key, cout = n.Count() });
            foreach (var item in groups)
            {
                if (item.cout > 1)
                {
                    b = false;
                    Msg = GlobalErrorType.GLOBAL_LANGUAGE_REPEAT_ERROR;
                    lan = item.Language;
                    break;
                }
            }
            return b;
        }

        protected override void BuliedTableResConfig(List<TableListHeaderModele> Headers, string pageType)
        {
            Dictionary<object, object> rule = new Dictionary<object, object>();
            rule.Add("required", true);
            rule.Add("message", this.Resources("reslaneerrormessage"));
            rule.Add("trigger", "change");
            Headers.Add(new TableListHeaderModele()
            {
                Key = "language",
                Name = Resources("language"),
                Align = "left",
                Options = this.Options,
                Rules = pageType != "view" ? new List<Dictionary<object, object>>() { rule } : new List<Dictionary<object, object>>(),
                Show = true,
                Editor = pageType != "view",
                ControlType = ControlType.parameter,
            });
            ///长度
            rule = new Dictionary<object, object>();
            rule.Add("min", 0);
            rule.Add("max", 200);
            rule.Add("message", this.Resources("resvaluelengthmsg"));
            rule.Add("trigger", "blur");
            Headers.Add(new TableListHeaderModele()
            {
                Key = "value",
                Name = Resources("value"),
                IsOperation = true,
                Align = "center",
                Rules = pageType != "view" ? new List<Dictionary<object, object>>() { rule } : new List<Dictionary<object, object>>(),
                Show = true,
                Editor = pageType != "view",
                ControlType = ControlType.textarea
            });
        }
        #endregion
    }
}
